package com.donger.iot.core.south.gateway.manager;

import com.donger.iot.core.south.gateway.access.DeviceAccessor;
import lombok.Data;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

/**
 * 设备接入线程池
 */
@Data
public class DeviceAccessorPoolExecutor extends ThreadPoolExecutor {
    /**
     * 运行中线程，所有的生产者线程都是DeviceAccessor的子类
     */
    private List<DeviceAccessor> aliveThreadList = new ArrayList<>();

    public DeviceAccessorPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime,
                                        TimeUnit unit,
                                        BlockingQueue<Runnable> workQueue) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
        aliveThreadList = new ArrayList<>();
    }

    public DeviceAccessorPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit,
                                        BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory);
        aliveThreadList = new ArrayList<>();
    }

    public DeviceAccessorPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit,
                                        BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, handler);
        aliveThreadList = new ArrayList<>();
    }

    public DeviceAccessorPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit,
                                        BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory,
                                        RejectedExecutionHandler handler) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler);
        aliveThreadList = new ArrayList<>();
    }
    /**
     * 线程运行完成后，剔除活跃线程
     */
    @Override
    protected void afterExecute(Runnable r, Throwable t) {
        this.aliveThreadList.remove(r);
        super.afterExecute(r, t);
    }

    /**
     * 重写执行线程
     * 在添加新线程时候，添加到aliveThreadList
     *
     * @param command 线程
     */
    public void execute(DeviceAccessor command) {
        if(command!=null){
            this.aliveThreadList.add(command);
            super.execute(command);
        }
    }
}
